From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Florian Westphal <fw@strlen.de>
Cc: Zihan Xi <zihanx@nebusec.ai>,
netfilter-devel@vger.kernel.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: Fri, 31 Jul 2026 12:18:12 +0200 [thread overview]
Message-ID: <amx2ZGHC7vIUaK48@chamomile> (raw)
In-Reply-To: <amuz5x-ib-Cuatcn@strlen.de>
On Thu, Jul 30, 2026 at 10:28:23PM +0200, Florian Westphal wrote:
> 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.
Please, also squash these two patches in one, they are basically the
same logical fix plus include the SCTP fix.
I would suggest you call this patch:
netfilter: nf_conntrack: defer invalid log until after unlock
Thanks.
prev parent reply other threads:[~2026-07-31 10:18 UTC|newest]
Thread overview: 7+ 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-31 10:26 ` Pablo Neira Ayuso
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
2026-07-31 10:18 ` Pablo Neira Ayuso [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=amx2ZGHC7vIUaK48@chamomile \
--to=pablo@netfilter.org \
--cc=avagin@gmail.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=fw@strlen.de \
--cc=horms@kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=pabeni@redhat.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox