All of lore.kernel.org
 help / color / mirror / Atom feed
From: Florian Westphal <fw@strlen.de>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Subject: Re: [PATCH nf] netfilter: conntrack: add dead flag to helpers
Date: Wed, 13 May 2026 12:05:02 +0200	[thread overview]
Message-ID: <agRMzvHgYCblnbrO@strlen.de> (raw)
In-Reply-To: <20260512205823.803476-1-pablo@netfilter.org>

Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> Add a new NF_CT_HELPER_F_DEAD helper flag to notify the packet path that
> this helper is going away. Thus, helpers are effectively disabled and no
> new expectations are created while removing the expectations created by
> this helper as well as unhelping the existing conntrack entries.
> 
> Add the check for NF_CT_HELPER_F_DEAD in the packet path to:
> - Conntrack confirmation path which invokes the helper callback.
> - Propagation of helper to conntrack via expectation.
> - OVS ct helper invocation.
> 
> Fixes: 12f7a505331e ("netfilter: add user-space connection tracking helper infrastructure")
> Reported-by: Florian Westphal <fw@strlen.de>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
>  include/net/netfilter/nf_conntrack_helper.h | 6 ++++++
>  net/netfilter/nf_conntrack_core.c           | 2 +-
>  net/netfilter/nf_conntrack_helper.c         | 5 ++++-
>  net/netfilter/nf_conntrack_ovs.c            | 3 +++
>  net/netfilter/nf_conntrack_proto.c          | 2 +-
>  5 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
> index de2f956abf34..1faa42efe42e 100644
> --- a/include/net/netfilter/nf_conntrack_helper.h
> +++ b/include/net/netfilter/nf_conntrack_helper.h
> @@ -25,6 +25,7 @@ struct module;
>  enum nf_ct_helper_flags {
>  	NF_CT_HELPER_F_USERSPACE	= (1 << 0),
>  	NF_CT_HELPER_F_CONFIGURED	= (1 << 1),
> +	NF_CT_HELPER_F_DEAD		= (1 << 2),
>  };
>  
>  #define NF_CT_HELPER_NAME_LEN	16
> @@ -63,6 +64,11 @@ struct nf_conntrack_helper {
>  	char nat_mod_name[NF_CT_HELPER_NAME_LEN];
>  };
>  
> +static inline bool nf_ct_helper_alive(const struct nf_conntrack_helper *helper)
> +{
> +	return likely(!(helper->flags & NF_CT_HELPER_F_DEAD));
> +}
> +
>  /* Must be kept in sync with the classes defined by helpers */
>  #define NF_CT_MAX_EXPECT_CLASSES	4
>  
> diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
> index 8ba5b22a1eef..d54da6babcfe 100644
> --- a/net/netfilter/nf_conntrack_core.c
> +++ b/net/netfilter/nf_conntrack_core.c
> @@ -1818,7 +1818,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
>  			/* exp->master safe, refcnt bumped in nf_ct_find_expectation */
>  			ct->master = exp->master;
>  			assign_helper = rcu_dereference(exp->assign_helper);
> -			if (assign_helper) {
> +			if (assign_helper && nf_ct_helper_alive(assign_helper)) {

At this time, the new ct isn't in any hash.  As-is, I don't think this
will guarantee such nfct canot escape.  See below.

>  				help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
>  				if (help)
>  					rcu_assign_pointer(help->helper, assign_helper);
> diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
> index b594cd244fe1..b3752ccca75e 100644
> --- a/net/netfilter/nf_conntrack_helper.c
> +++ b/net/netfilter/nf_conntrack_helper.c
> @@ -415,8 +415,11 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
>  	nf_ct_helper_count--;
>  	mutex_unlock(&nf_ct_helper_mutex);
>  
> +	me->flags |= NF_CT_HELPER_F_DEAD;
> +

Does this need to be toggled while under lock?
I don't think synchronize_rcu() is a barrier.

Also, it looks like this can be racing with nfnl_cthelper_update().
We probably need to add some new lock, or reuse existing one like
nf_ct_helper_mutex, or expectation spinlock.

>  	/* Make sure every nothing is still using the helper unless its a
> -	 * connection in the hash.
> +	 * connection in the hash, no more expectations are created after
> +	 * this rcu grace period.
>  	 */
>  	synchronize_rcu();

... that makes things wait until we leave rcu protection.
I think we should also drop nfqueued packets here to make sure
they can't be reinjected.

Also, should __nf_ct_expect_check() also call nf_ct_helper_alive()
and refuse insertion of such exp into the table?

That would give following unreg sequence:
1. Unlink from hash
2. set flag -> prevent concurrent nf_ct_expect_related() from
   adding more expectations to the exp table
3. synchronize_rcu() -> all skbs that had this helper have
   left RCU protection
4. nf_ct_expect_iterate_destroy() removes all not-yet-found
   exp entries from table
5. nf_ct_iterate_destroy() -> clear exp from nf_conn's that are
   *in conntrack table*

That still means we could have a NEW conntrack queued via nfqueue.
I think we also need to toss nfqueued packets after step 3) and
need to refuse queueing to userspace if the flag is set (-> drop).

We could have several nfqueue back to back:
-t mangle -A PREROUTING -j NFQUEUE
-t mangle -A FORWARD -j NFQUEUE

... and each synchronize_rcu() might advance skb to next
'queue' instead of nf_confirm().

But I think that this a good direction, I think its better than my
rather destructive temporarily-block-all-exps idea.

  reply	other threads:[~2026-05-13 10:05 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-12 20:58 [PATCH nf] netfilter: conntrack: add dead flag to helpers Pablo Neira Ayuso
2026-05-13 10:05 ` Florian Westphal [this message]
2026-05-13 15:29   ` Pablo Neira Ayuso
2026-05-13 15:38     ` Pablo Neira Ayuso
2026-05-13 15:52       ` 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=agRMzvHgYCblnbrO@strlen.de \
    --to=fw@strlen.de \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.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.