All of lore.kernel.org
 help / color / mirror / Atom feed
From: Florian Westphal <fw@strlen.de>
To: Zihan Xi <zihanx@nebusec.ai>
Cc: netfilter-devel@vger.kernel.org, pablo@netfilter.org,
	phil@nwl.cc, davem@davemloft.net, edumazet@google.com,
	pabeni@redhat.com, horms@kernel.org, avagin@gmail.com,
	vega@nebusec.ai
Subject: Re: [PATCH nf v2 2/2] netfilter: nf_conntrack_tcp: defer tcp_in_window invalid logging until after unlock
Date: Thu, 30 Jul 2026 22:28:23 +0200	[thread overview]
Message-ID: <amuz5x-ib-Cuatcn@strlen.de> (raw)
In-Reply-To: <27612fbff3730c5d63a0e3fb0f51aeeed77ed5d7.1785348197.git.zihanx@nebusec.ai>

Zihan Xi <zihanx@nebusec.ai> wrote:
> tcp_in_window() can emit several invalid-packet logs while ct->lock is
> still held.  If invalid logging is routed to nfnetlink_log with
> conntrack export enabled, this can re-enter conntrack netlink glue and
> recurse into tcp_to_nlattr() on the same conntrack.
> 
> Fix this by storing only the minimal invalid-log context for the
> remaining tcp_in_window() cases and emitting the actual log after
> releasing ct->lock.  Rename the helper to reflect that it now records
> context instead of logging immediately, and add an explicit lockdep
> assertion plus comment to document that invalid TCP logs must not be
> emitted while ct->lock is held.
> 
> Fixes: d48668052b26 ("netfilter: fix nf_l4proto_log_invalid to log invalid packets")
> Cc: stable@vger.kernel.org
> Reported-by: Vega <vega@nebusec.ai>
> Assisted-by: Codex:gpt-5.4
> Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
> ---
> changes in v2:
>   - Keep only the tcp_in_window() invalid logging cases in this patch.
>   - Rename the helper to reflect that it stores invalid-log context.
>   - Add a lockdep assertion and comment documenting that invalid logs must not be emitted under ct->lock.
>   - v1 Link: https://lore.kernel.org/all/cover.1785307980.git.zihanx@nebusec.ai/
> ---
>  net/netfilter/nf_conntrack_proto_tcp.c | 113 ++++++++++++++++++-------
>  1 file changed, 82 insertions(+), 31 deletions(-)
> 
> diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
> index ef31dcaffd19..e5875b7528fe 100644
> --- a/net/netfilter/nf_conntrack_proto_tcp.c
> +++ b/net/netfilter/nf_conntrack_proto_tcp.c
> @@ -480,37 +480,87 @@ static void tcp_init_sender(struct ip_ct_tcp_state *sender,
>  	}
>  }
>  
> -__printf(6, 7)
> -static enum nf_ct_tcp_action nf_tcp_log_invalid(const struct sk_buff *skb,
> -						const struct nf_conn *ct,
> -						const struct nf_hook_state *state,
> -						const struct ip_ct_tcp_state *sender,
> -						enum nf_ct_tcp_action ret,
> -						const char *fmt, ...)
> +enum nf_tcp_invalid_log_type {
> +	NF_TCP_LOG_NONE,
> +	NF_TCP_LOG_OVERSHOT,
> +	NF_TCP_LOG_SEQ_OVER,
> +	NF_TCP_LOG_ACK_OVER,
> +	NF_TCP_LOG_SEQ_UNDER,
> +	NF_TCP_LOG_ACK_UNDER,
> +};
> +
> +struct nf_tcp_invalid_log {
> +	enum nf_tcp_invalid_log_type type;
> +	u32 value;
> +};
> +
> +static enum nf_ct_tcp_action
> +nf_tcp_store_invalid(const struct nf_conn *ct,
> +		     const struct ip_ct_tcp_state *sender,
> +		     struct nf_tcp_invalid_log *log,
> +		     enum nf_ct_tcp_action ret,
> +		     enum nf_tcp_invalid_log_type type,
> +		     u32 value)
>  {
>  	const struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct));
> -	struct va_format vaf;
> -	va_list args;
>  	bool be_liberal;
>  
>  	be_liberal = sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || tn->tcp_be_liberal;
>  	if (be_liberal)
>  		return NFCT_TCP_ACCEPT;
>  
> -	va_start(args, fmt);
> -	vaf.fmt = fmt;
> -	vaf.va = &args;
> -	nf_ct_l4proto_log_invalid(skb, ct, state, "%pV", &vaf);
> -	va_end(args);
> -
> +	log->type = type;
> +	log->value = value;
>  	return ret;
>  }
>  
> +static void nf_tcp_log_invalid(const struct sk_buff *skb,
> +			       const struct nf_conn *ct,
> +			       const struct nf_hook_state *state,
> +			       const struct nf_tcp_invalid_log *log)
> +{
> +	/* nfnetlink_log may re-enter conntrack attribute dumping and try to
> +	 * take ct->lock again via tcp_to_nlattr(), so invalid TCP logs must
> +	 * only be emitted after dropping ct->lock.
> +	 */
> +	lockdep_assert_not_held(&ct->lock);
> +
> +	switch (log->type) {
> +	case NF_TCP_LOG_OVERSHOT:
> +		nf_ct_l4proto_log_invalid(skb, ct, state,
> +					  "%u bytes more than expected",
> +					  log->value);

Can you move the comment and the lockdep assert into
nf_ct_l4proto_log_invalid() so we can catch offenders outside
tcp as well?

SCTP seems to be buggy as well.

Other than that:

Reviewed-by: Florian Westphal <fw@strlen.de>

You can keep this tag in next iteration.

      reply	other threads:[~2026-07-30 20:28 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-30 13:55 [PATCH nf v2 0/2] netfilter: fix TCP conntrack invalid-log deadlock Zihan Xi
2026-07-30 13:55 ` [PATCH nf v2 1/2] netfilter: nf_conntrack_tcp: defer timeout-lowering invalid log until after unlock Zihan Xi
2026-07-30 20:25   ` Florian Westphal
2026-07-30 13:55 ` [PATCH nf v2 2/2] netfilter: nf_conntrack_tcp: defer tcp_in_window invalid logging " Zihan Xi
2026-07-30 20:28   ` Florian Westphal [this message]

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=amuz5x-ib-Cuatcn@strlen.de \
    --to=fw@strlen.de \
    --cc=avagin@gmail.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pablo@netfilter.org \
    --cc=phil@nwl.cc \
    --cc=vega@nebusec.ai \
    --cc=zihanx@nebusec.ai \
    /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.