From: Florian Westphal <fw@strlen.de>
To: Alexander Atanasov <alexander.atanasov@virtuozzo.com>
Cc: netdev@vger.kernel.org
Subject: Re: [PATCH] netfilter: nf_tables: always synchronize with readers before releasing tables
Date: Mon, 27 Feb 2023 13:44:02 +0100 [thread overview]
Message-ID: <20230227124402.GA30043@breakpoint.cc> (raw)
In-Reply-To: <901abd29-9813-e4fe-c1db-f5273b1c55e3@virtuozzo.com>
Alexander Atanasov <alexander.atanasov@virtuozzo.com> wrote:
> general protection fault, probably for non-canonical
> address 0xdead000000000115: 0000 [#1] PREEMPT SMP NOPTI
> RIP: 0010:__nf_tables_dump_rules+0x10d/0x170 [nf_tables]
>
> __nf_tables_dump_rules runs under rcu_read_lock while __nft_release_table
> is called from nf_tables_exit_net. commit_mutex is held inside
> nf_tables_exit_net but this is not enough to guard against
> lockless readers. When __nft_release_table does list_del(&rule->list)
> next ptr is poisoned and it crashes while walking the list.
>
> Before calling __nft_release_tables all lockless readers must be done -
> to ensure this a call to synchronize_rcu() is required.
>
> nf_tables_exit_net does this in case there is something to abort
> inside __nf_tables_abort but it does not do so otherwise.
> Fix this by add the missing synchronize_rcu() call before calling
> __nft_release_table in the nothing to abort case.
>
> Fixes: 6001a930ce03 ("netfilter: nftables: introduce table ownership")
> Signed-off-by: Alexander Atanasov <alexander.atanasov@virtuozzo.com>
> ---
> net/netfilter/nf_tables_api.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> index d73edbd4eec4..849523ece109 100644
> --- a/net/netfilter/nf_tables_api.c
> +++ b/net/netfilter/nf_tables_api.c
> @@ -10333,9 +10333,15 @@ static void __net_exit nf_tables_exit_net(struct
> net *net)
> struct nftables_pernet *nft_net = nft_pernet(net);
> mutex_lock(&nft_net->commit_mutex);
> + /* Need to call synchronize_rcu() to let any active rcu lockless
> + * readers to finish. __nf_tables_abort does this internaly so
> + * only call it here if there is nothing to abort.
> + */
> if (!list_empty(&nft_net->commit_list) ||
> !list_empty(&nft_net->module_list))
> __nf_tables_abort(net, NFNL_ABORT_NONE);
> + else
> + synchronize_rcu();
Wouldn't it be better to just drop those list_empty() checks?
AFAICS __nf_tables_abort will DTRT in that case.
You can still add a comment like the one you added above to make
it clear that we also need to wait for those readers to finish.
Lastly, that list_del() in __nft_release_basechain should probably
be list_del_rcu()?
next prev parent reply other threads:[~2023-02-27 12:44 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20230227121720.3775652-1-alexander.atanasov@virtuozzo.com>
2023-02-27 12:21 ` [PATCH] netfilter: nf_tables: always synchronize with readers before releasing tables Alexander Atanasov
2023-02-27 12:44 ` Florian Westphal [this message]
2023-02-27 13:43 ` Alexander Atanasov
[not found] ` <20230227161140.GA31439@breakpoint.cc>
2023-02-27 18:50 ` Alexander Atanasov
2023-02-27 23:31 ` Florian Westphal
2023-02-28 9:54 ` Alexander Atanasov
2023-02-28 10:59 ` Florian Westphal
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=20230227124402.GA30043@breakpoint.cc \
--to=fw@strlen.de \
--cc=alexander.atanasov@virtuozzo.com \
--cc=netdev@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.