From: David Lee <david.lee@trailofbits.com>
To: pablo@netfilter.org, fw@strlen.de, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com
Cc: David Lee <david.lee@trailofbits.com>,
Kyle Zeng <kylebot@openai.com>,
Dominik 'Disconnect3d' Czarnota
<dominik.czarnota@trailofbits.com>,
phil@nwl.cc, horms@kernel.org, netfilter-devel@vger.kernel.org,
coreteam@netfilter.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH] netfilter: nf_conntrack: prevent helper extension relocation
Date: Fri, 31 Jul 2026 14:08:10 +0000 [thread overview]
Message-ID: <20260731140811.566714-1-david.lee@trailofbits.com> (raw)
struct nf_conn_help contains the head of the per-master expectation
list. hlist_add_head_rcu() makes the first expectation node point back to
that head, but nf_ct_ext_add() can later move the extension buffer with
krealloc(). This leaves the node backpointer aimed at freed memory, so
unlinking the expectation writes through a stale pointer.
Reserve the full u8-addressable extension space when adding the helper
extension and reuse the existing buffer once the helper is present. This
keeps the expectation list head stable while allowing later extensions
to be added.
Fixes: 857b46027d6f ("netfilter: nft_ct: add ct expectations support")
Bug found and triaged by OpenAI Security Research and
validated by Trail of Bits.
Assisted-by: Codex:gpt-5.6-sol gpt-5.5-cyber
Signed-off-by: Kyle Zeng <kylebot@openai.com>
---
Trail of Bits has a reproducer for this bug that triggers a
KASAN use-after-free and can share if needed.
net/netfilter/nf_conntrack_extend.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
index 0da105e1d..1421944a3 100644
--- a/net/netfilter/nf_conntrack_extend.c
+++ b/net/netfilter/nf_conntrack_extend.c
@@ -112,9 +112,21 @@ void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
newlen = newoff + nf_ct_ext_type_len[id];
alloc = max(newlen, NF_CT_EXT_PREALLOC);
- new = krealloc(ct->ext, alloc, gfp);
- if (!new)
- return NULL;
+ /*
+ * Once an expectation is linked, its list node points back to the
+ * hlist head in the helper extension. Reserve all available extension
+ * space for the helper and do not move it afterward.
+ */
+ if (ct->ext &&
+ __nf_ct_ext_exist(ct->ext, NF_CT_EXT_HELPER)) {
+ new = ct->ext;
+ } else {
+ if (id == NF_CT_EXT_HELPER)
+ alloc = U8_MAX;
+ new = krealloc(ct->ext, alloc, gfp);
+ if (!new)
+ return NULL;
+ }
if (!ct->ext)
memset(new->offset, 0, sizeof(new->offset));
--
2.53.0
next reply other threads:[~2026-07-31 14:08 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 14:08 David Lee [this message]
2026-07-31 15:37 ` [PATCH] netfilter: nf_conntrack: prevent helper extension relocation 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=20260731140811.566714-1-david.lee@trailofbits.com \
--to=david.lee@trailofbits.com \
--cc=coreteam@netfilter.org \
--cc=davem@davemloft.net \
--cc=dominik.czarnota@trailofbits.com \
--cc=edumazet@google.com \
--cc=fw@strlen.de \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=kylebot@openai.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pablo@netfilter.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 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.