* [PATCH nf] netfilter: nf_conntrack: move expectation hlist_head on ct extension realloc
@ 2026-07-29 0:16 Pablo Neira Ayuso
2026-07-29 0:39 ` Pablo Neira Ayuso
0 siblings, 1 reply; 2+ messages in thread
From: Pablo Neira Ayuso @ 2026-07-29 0:16 UTC (permalink / raw)
To: netfilter-devel
Commit 7c9664351980 ("netfilter: move nat hlist_head to nf_conn") moved
the nat hlist_head to nf_conn and it removes the .move callback for ct
extensions. This commit description already points to the same problem
that is being addressed for expectations by this patch:
1. ...
2. When reallocation of extension area occurs we need to fixup the
bysource hash head via hlist_replace_rcu.
This means that the .pprev pointer of the first expectation might refer
to a stale hlist_head after reallocation.
This bug is now easier to trigger since the introduction of the commit
857b46027d6f ("netfilter: nft_ct: add ct expectations support") which
allows to create expectations before the ct extension area have been
fully set up for unconfirmed conntracks.
This patch uses hlist_move_list() because this conntrack is unconfirmed,
ie. not yet in the hashes, and it is neither visible to the conntrack
garbage collector nor ctnetlink.
Fixes: 857b46027d6f ("netfilter: nft_ct: add ct expectations support")
Reported-by: Jaeyeong Lee <iostreampy@proton.me>
Link: https://patch.msgid.link/20260715144755.00ea7dfcd9f@proton.me
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_extend.c | 33 ++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
index 0da105e1ded9..ea7795a2461f 100644
--- a/net/netfilter/nf_conntrack_extend.c
+++ b/net/netfilter/nf_conntrack_extend.c
@@ -87,9 +87,34 @@ static __always_inline unsigned int total_extension_size(void)
;
}
+static void nf_ct_ext_helper_save(struct nf_conn *ct,
+ struct hlist_head *expectations)
+{
+ struct nf_conn_help *help;
+
+ help = nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
+ if (!help)
+ return;
+
+ hlist_move_list(&help->expectations, expectations);
+}
+
+static void nf_ct_ext_helper_restore(struct nf_conn *ct,
+ struct hlist_head *expectations)
+{
+ struct nf_conn_help *help;
+
+ help = nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
+ if (!help)
+ return;
+
+ hlist_move_list(expectations, &help->expectations);
+}
+
void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
{
unsigned int newlen, newoff, oldlen, alloc;
+ HLIST_HEAD(expectations);
struct nf_ct_ext *new;
/* Conntrack must not be confirmed to avoid races on reallocation. */
@@ -108,13 +133,17 @@ void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
oldlen = sizeof(*new);
}
+ nf_ct_ext_helper_save(ct, &expectations);
+
newoff = ALIGN(oldlen, __alignof__(struct nf_ct_ext));
newlen = newoff + nf_ct_ext_type_len[id];
alloc = max(newlen, NF_CT_EXT_PREALLOC);
new = krealloc(ct->ext, alloc, gfp);
- if (!new)
+ if (!new) {
+ nf_ct_ext_helper_restore(ct, &expectations);
return NULL;
+ }
if (!ct->ext)
memset(new->offset, 0, sizeof(new->offset));
@@ -124,6 +153,8 @@ void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
memset((void *)new + newoff, 0, newlen - newoff);
ct->ext = new;
+ nf_ct_ext_helper_restore(ct, &expectations);
+
return (void *)new + newoff;
}
EXPORT_SYMBOL(nf_ct_ext_add);
--
2.47.3
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH nf] netfilter: nf_conntrack: move expectation hlist_head on ct extension realloc
2026-07-29 0:16 [PATCH nf] netfilter: nf_conntrack: move expectation hlist_head on ct extension realloc Pablo Neira Ayuso
@ 2026-07-29 0:39 ` Pablo Neira Ayuso
0 siblings, 0 replies; 2+ messages in thread
From: Pablo Neira Ayuso @ 2026-07-29 0:39 UTC (permalink / raw)
To: netfilter-devel
On Wed, Jul 29, 2026 at 02:16:45AM +0200, Pablo Neira Ayuso wrote:
> Commit 7c9664351980 ("netfilter: move nat hlist_head to nf_conn") moved
> the nat hlist_head to nf_conn and it removes the .move callback for ct
> extensions. This commit description already points to the same problem
> that is being addressed for expectations by this patch:
>
> 1. ...
> 2. When reallocation of extension area occurs we need to fixup the
> bysource hash head via hlist_replace_rcu.
>
> This means that the .pprev pointer of the first expectation might refer
> to a stale hlist_head after reallocation.
>
> This bug is now easier to trigger since the introduction of the commit
> 857b46027d6f ("netfilter: nft_ct: add ct expectations support") which
> allows to create expectations before the ct extension area have been
> fully set up for unconfirmed conntracks.
>
> This patch uses hlist_move_list() because this conntrack is unconfirmed,
> ie. not yet in the hashes, and it is neither visible to the conntrack
> garbage collector nor ctnetlink.
Scratch this iteration, ctnetlink_del_expect() can reach the
expectation.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-29 0:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-29 0:16 [PATCH nf] netfilter: nf_conntrack: move expectation hlist_head on ct extension realloc Pablo Neira Ayuso
2026-07-29 0:39 ` Pablo Neira Ayuso
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.