Look up another CVE · open CVE-2026-90237 in the interactive tracker
CVE-2026-90237
netfilter: nft_ct: move custom expectation support to helper
Published 2026-09-17 (31 days ago) by the Linux kernel CNA. Subsystem include/net. Debian urgency: not yet assigned.
What to do, per Debian release
Debian's own status for CVE-2026-90237 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source
| Release | Status | Version | What this means |
|---|---|---|---|
| Debian 12bookworm | vulnerable | 6.1.190-1 | No fix published anywhere yet, neither in Debian nor upstream for the series bookworm tracks. Watch the Debian tracker page for this CVE. Advisories for bookworm have historically landed a median of 23 days after publication. |
| Debian 13trixie | vulnerable | 6.12.113-1 | No fix published anywhere yet, neither in Debian nor upstream for the series trixie tracks. Watch the Debian tracker page for this CVE. Advisories for trixie have historically landed a median of 11 days after publication. |
| Debian 14forky | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
| Debian unstablesid | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
The vulnerability
What the bug is
Originally, the ct expectation support called nf_ct_helper_ext_add() for confirmed conntracks, which is invalid, triggering a splat. This was fixed by commit 1710eb913bdc ("netfilter: nft_ct: skip expectations for confirmed conntrack") which restricted it to unconfirmed conntracks. However, early insertion of expectations into the expectations list when the conntrack is unconfirmed leads to stale entries pointing to the wrong hlist_head through .pprev due to ct extension reallocation. Commit 7c9664351980 ("netfilter: move nat hlist_head to nf_conn") moved the nat hlist_head to nf_conn for this reason: 1. ... 2. When reallocation of extension area occurs we need to fixup the bysource hash head via hlist_replace_rcu. I'd rather not increase the size of the struct nf_conn for this feature has very limited scope: only one expectation can be created at a time given expect_clash() will make nf_ct_expect_related() reports EBUSY. For this reason, relax nf_ct_expect_related() not to drop packets in case expectation creation fails, therefore, expectation creation becomes best effort. To address this issue, add an internal ct helper and attach it to the conntrack entry to streamline the custom ct expectation support with existing ct helpers. Expose a new nf_conntrack_helper_release() function to release the internal helper that is allocated and attached to the conntrack entry to create the custom expectations. The nft_ct module removal always waits for rcu grace period, then the NULL helper callback is observed after this. This patch also restricts the creation of expectations to different helpers other than this custom helper that is created for this type of expectations.
Where it lives
The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.
include/net/netfilter/nf_conntrack_helper.h
net/netfilter/nf_conntrack_helper.c
net/netfilter/nft_ct.c
- What this is
- NETFILTERMAINTAINERS section matched on include/net/netfilter/ · netfilter-devel@vger.kernel.org · Maintained
- Kernel module
- nf_conntrack
Check it on the machine
grep -wE 'CONFIG_NETFILTER|CONFIG_NF_CONNTRACK' /boot/config-$(uname -r)Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.
lsmod | grep -w nf_conntrackPrints a line if that module is loaded right now, and nothing if it is not. One that is not loaded can still be loaded later by anything that needs it.
Show whether Debian builds this, per release
Debian builds this as a loadable module. Every release below compiles it as a module on every flavour, so whether the code is in the running kernel depends on whether that module is loaded.
- bookworm, trixie, forky, sidm
- m
- a loadable module on every flavour - check lsmod, can be blacklisted
- Build switches
- CONFIG_NETFILTER, CONFIG_NF_CONNTRACK
- Reads as
- all on means the file is compiled; any one off means it is not.
From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages
Signals
- Published
- 2026-09-17 (31 days ago)source
- CVSS
- 7.8 high
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Hsource recompute it - Attack vector
- local (AV:L)source
- EPSS
- 0.17%, higher than 5.4% of all CVEssource
- CISA KEV
- not listedthe KEV catalogue
- Debian urgency
- not yet assignedsource
- Subsystem
- include/net
Upstream fixes
The versions the CNA records as introducing and fixing this, and the commit for each. source
| Introduced | Fixed in | Commit |
|---|---|---|
| 5.3 | 7.2.6 | af3fe52fd108 |
| 5.3 | 7.3 | 3679da4ad8be |
Why the CNA scored it this way
Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source
- AV:LAttack vector, local
- The triggering state is created by a local NFT_MSG_NEWOBJ (nf_tables_newobj) of type NFT_OBJECT_CT_EXPECT plus an objref rule; nft_objref_eval then calls nft_ct_expect_obj_eval from nft_do_chain_ipv4 on a packet the attacker sends in their netns. No remote protocol field carries the malformed expectation-list linkage.
- AC:LAttack complexity, low
- After nf_ct_expect_insert stores exp->lnode into nf_conn_help.expectations, the attacker’s later expressions on the same packet (nft_ct_timeout_obj_eval, nft_ct_set_eval NFT_CT_EVENTMASK, or nft_nat_eval → nf_nat_setup_info → nfct_seqadj_ext_add) call nf_ct_ext_add so krealloc moves ct->ext; that rule order is attacker-chosen and needs no race.
- PR:LPrivileges required, low
- nfnetlink_rcv admits the NFT_MSG_NEWOBJ/NEWRULE batch only after netlink_net_capable(skb, CAP_NET_ADMIN) against sock_net(skb->sk)->user_ns, which an unprivileged user gets via unshare -Urn; nft_ct_expect_obj_init has no extra init-namespace capability check.
- UI:NUser interaction, none
- The attacker installs the ct expectation object and objref rule themselves, then emits their own UDP/TCP packet so nft_do_chain_ipv4 at NF_INET_LOCAL_OUT reaches nft_ct_expect_obj_eval; no other user must mount, open a file, or confirm the ruleset.
- S:UScope, unchanged
- krealloc of ct->ext leaves a dangling hlist_node.pprev in the host kernel heap (nf_conn_help.expectations); impact is in-kernel memory corruption on the same host, not a KVM/Xen guest-to-host escape or IOMMU/DMA bypass.
- C:HConfidentiality impact, high
- After nf_ct_ext_add’s krealloc frees the old nf_conn_help, exp->lnode.pprev still addresses that slab; spraying it and then walking help->expectations in nf_ct_remove_expectations is a use-after-free read of reused kernel memory.
- I:HIntegrity impact, high
- nf_ct_unlink_expect_report’s hlist_del_rcu(&exp->lnode) writes the next pointer through the stale pprev into the freed helper extension, a heap write primitive that can be groomed for control-flow hijack.
- A:HAvailability impact, high
- The same dangling pprev is used when the conntrack is destroyed (clean_from_lists → nf_ct_remove_expectations) or the expectation is unlinked, which oopses or panics if the old ct->ext slab was reused or poisoned.