Conversation
jira VULN-177693 cve-pre CVE-2026-23231 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit d9246a5 Update nft_flowtable_parse_hook() to take the flowtable hook list as parameter. This allows to reuse this function to update the hooks. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> (cherry picked from commit 48af0290d8c2269ad2b4484236ca7cb5d9d93ce5) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
…et_hooks() jira VULN-177693 cve-pre CVE-2026-23231 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit f938266 This patch prepares for incremental flowtable hook updates. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> (cherry picked from commit 0ee7a3ed38aedbf30b214b67e08bc198d68b32fc) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-177693 cve-pre CVE-2026-23231 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit 389a2cb This patch adds a helper function destroy the flowtable hooks. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> (cherry picked from commit 5af8e7f44f027717c8ce86b63b056332b2155812) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-177693 cve-pre CVE-2026-23231 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit 04b7db4 This patch adds a helper function to add the chain to the hashtable and the chain list. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> (cherry picked from commit c62ae2d56890e450e4c784ebea4d73e7970c4381) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-177693 cve-pre CVE-2026-23231 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit cdc3254 upstream-diff Ignored changes in functions `nft_commit_release', `nf_tables_abort_release', because the function being renamed is not used there (missing abadb2f and 78d9f48). Rename nft_flowtable_hooks_destroy() by nft_hooks_destroy() to prepare for netdev chain device updates. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> (cherry picked from commit 465373ff4e04b41b193adaecb1a79bc35965e890) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
…able jira VULN-177693 cve-pre CVE-2026-23231 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit d472e98 upstream-diff | 1. Needed to add forward declaration of `nft_chain_del()' so that it could have been used in the earlier-defined `nf_tables_addchain()'. In the upstream the ordering of definitions doesn't play a role because `nft_chain_del()' was made public in d0e2c7d (`netfilter: nf_tables: add NFT_CHAIN_BINDING') and declared in the nf_tables.h header. 2. In `nf_tables_addchain()' preserved the intent of the change (moving `nf_tables_register_hook()' call to the end of the function), while taking into account the deviations from the upstream. 1. Re-arranged the cleanup ladder and goto targets to ensure every allocator is paired with the corresponding deallocator. Alloc Dealloc -------------------------------------------------------- ctx->chain contruction nf_tables_chain_destroy() nf_tables_register_hook() nf_tables_unregister_hook() nft_chain_add() nft_chain_del() nft_trans_chain_add() nft_trans_destroy() Took into account the missing 1689f25 (`netfilter: nf_tables: report use refcount overflow') which otherwise would require `nft_use_dec_restore()' to include. 2. Introduced the new label names. This is a combined relabeling done by upstream commits 002f217 (`netfilter: nf_tables: add userdata attributes to nft_chain') and this one, d472e98. Commit 002f217 wasn't backported separately because the relabeling was coupled with other, functional changes. The label names were chosen to correspond, on the upstream, to the ones marking the same deallocator (`nft_use_dec_restore()' is missing in LTS 8.6 so no `err_trans' label). Register hooks last when adding chain/flowtable to ensure that packets do not walk over datastructure that is being released in the error path without waiting for the rcu grace period. Fixes: 91c7b38 ("netfilter: nf_tables: use new transaction infrastructure to handle chain") Fixes: 3b49e2e ("netfilter: nf_tables: add flow table netlink frontend") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> (cherry picked from commit 9c03d4d752584aeec7a87965780e409ce2c93908) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-177693 cve CVE-2026-23231 commit-author Inseo An <y0un9sa@gmail.com> commit 71e99ee nf_tables_addchain() publishes the chain to table->chains via list_add_tail_rcu() (in nft_chain_add()) before registering hooks. If nf_tables_register_hook() then fails, the error path calls nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy() with no RCU grace period in between. This creates two use-after-free conditions: 1) Control-plane: nf_tables_dump_chains() traverses table->chains under rcu_read_lock(). A concurrent dump can still be walking the chain when the error path frees it. 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly installs the IPv4 hook before IPv6 registration fails. Packets entering nft_do_chain() via the transient IPv4 hook can still be dereferencing chain->blob_gen_X when the error path frees the chain. Add synchronize_rcu() between nft_chain_del() and the chain destroy so that all RCU readers -- both dump threads and in-flight packet evaluation -- have finished before the chain is freed. Fixes: 91c7b38 ("netfilter: nf_tables: use new transaction infrastructure to handle chain") Signed-off-by: Inseo An <y0un9sa@gmail.com> Signed-off-by: Florian Westphal <fw@strlen.de> (cherry picked from commit 025f243c144afd6177d8babd7c3f1f7e95775863) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-179371 cve CVE-2026-23392 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit d73f4b5 Call synchronize_rcu() after unregistering the hooks from error path, since a hook that already refers to this flowtable can be already registered, exposing this flowtable to packet path and nfnetlink_hook control plane. This error path is rare, it should only happen by reaching the maximum number hooks or by failing to set up to hardware offload, just call synchronize_rcu(). There is a check for already used device hooks by different flowtable that could result in EEXIST at this late stage. The hook parser can be updated to perform this check earlier to this error path really becomes rarely exercised. Uncovered by KASAN reported as use-after-free from nfnetlink_hook path when dumping hooks. Fixes: 3b49e2e ("netfilter: nf_tables: add flow table netlink frontend") Reported-by: Yiming Qian <yimingqian591@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de> (cherry picked from commit 54a8908f0d227c81a0c8b36d0a522911918a9677) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
pvts-mat
force-pushed
the
CVE-batch-46_ciqlts8_6
branch
from
September 22, 2026 17:07
4bd41c0 to
d2e8aef
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[LTS 8.6]
PR structure
The PR addresses two closely related cves CVE-2026-23231 and CVE-2026-23392.
The fixing commits rest on a common prerequisite d472e98
netfilter: nf_tables: register hooks last when adding new chain/flowtable. The rest of the commits are the prerequisites for this prerequisite - marked all ascve-pre CVE-2026-23231though could have beencve-pre CVE-2026-23392as well.While the fixes are very simple (one line added) the problem being solved was far from it, which necessitated deeper analysis before transfering them to LTS 8.6.
Commits
Explanation
CVE-2026-23392
Background
The bug is related to building a netfilter transaction, for example during the execution of a script like below
The modified function is what builds a flowtable, the object
fin the example above. Regular firewall rules apply to each packet separately, despite most of them addressing a particular packet flow, defined as all the packets belonging to the same connection. Flowtables were introduced to leverage this and greatly optimize throughput by reducing the regular rules checking to only the handshake packets, the rest of connection bypassing the expensive checks, through a flowtable. Flowtables are inherently associated with network devices.Tracking the UAF and problem explanation
The bugfixing commit mesasge mentions
The exact KASAN log with the stack trace leading to UAF could not have been found. However, it most likely refers to the
net/netfilter/nfnetlink_hook.cfile, the.dumpoperation, as the entry point:kernel-src-tree/net/netfilter/nfnetlink_hook.c
Line 442 in d73f4b5
The UAF is strictly related to the flowtables, as the commit's subject states
(meaning what caused UAF was releasing flowtable before rcu grace period). The only place in
net/netfilter/nfnetlink_hook.cdealing with flowtables is thenfnl_hook_put_nft_ft_info()function. This gives the most likely UAF stack trace:kernel-src-tree/net/netfilter/nfnetlink_hook.c
Line 442 in d73f4b5
nfnl_hook_dump()::kernel-src-tree/net/netfilter/nfnetlink_hook.c
Lines 368 to 369 in d73f4b5
nfnl_hook_dump_one()::kernel-src-tree/net/netfilter/nfnetlink_hook.c
Line 259 in d73f4b5
nfnl_hook_put_nft_ft_info::Perhaps
nfnl_hook_put_nft_ft_infois not even reached, with UAF occuring at theops->privdereference passed asnf_ftargument. This covers the UAF reached from the control plane, meaning from the administrator manipulating the settings, like callingnft -a list hookswhich would reach the code above. Note that this functionality is not available in LTS 8.6 (started from the non-backported e2cf17dnetfilter: add new hook nfnl subsystem), which means that the specific KASAN error path addressed by CVE-2026-23392 fix doesn't apply to this version.However, the UAF is also possible from the data plane, meaning from the processing of packets. This is the packet path being mentioned in the bugfix message:
The entry point for both of these cases are the ingress hooks from the
net_devicestruct. The complete chain of dereferences leading from the hooks to flowtables is rather obfuscatedstruct net_devicekernel-src-tree/include/linux/netdevice.h
Line 2135 in 3e82baa
struct nf_hook_entrieskernel-src-tree/include/linux/netfilter.h
Line 96 in 3e82baa
It's a flexible array member, see how the field is obtained with
nf_hook_entries_get_hook_ops():kernel-src-tree/include/linux/netfilter.h
Lines 105 to 113 in 3e82baa
struct nf_hook_opskernel-src-tree/include/linux/netfilter.h
Line 68 in 3e82baa
The
void*member priv is an allocatednf_flowtableobject, seekernel-src-tree/net/netfilter/nf_tables_api.c
Line 6557 in 533c446
called from the fix-modified
nf_tables_newflowtable(), atkernel-src-tree/net/netfilter/nf_tables_api.c
Lines 6751 to 6752 in 533c446
The core of the CVE-2026-23392 issue is that as long as
nf_hooks_ingresspointer innet_deviceis alive the flowtable object accessible to it through the chain above must be alive as well. The deallocation ofnf_hooks_ingressobject is done during the rollback of registered hooks in case ofnft_register_flowtable_net_hooks()error (nft_unregister_flowtable_hook(…)→nf_unregister_net_hook(…)→__nf_unregister_net_hook(…)→nf_hook_entries_free(p)) and delegated the end of the RCU grace periodkernel-src-tree/net/netfilter/core.c
Line 88 in 533c446
while the deallocation of a flowtable in the error path of
nf_tables_newflowtable()function is simply done on demand, at the end of itkernel-src-tree/net/netfilter/nf_tables_api.c
Line 6780 in 533c446
which may come earlier, chronologically.
The fix in commit d73f4b5 calls
synchronize_rcu()before freeing the flowtable, which simply blocks the thread until the end of grace period. This is usually very costly time-wise, and that's why the author justifies the decision:CVE-2026-23231
The CVE-2026-23231 problem is exactly the same as CVE-2026-23392, except with chains instead of flowtables. Unlike in CVE-2026-23392 case the commit message for the CVE-2026-23231 fix is well composed and clearly explains the problem and its solution, not requiring additional unpacking
A minor difference in the context of the LTS 8.6 backport is that the
nf_tables_dump_chains()function exists in LTS 8.6, unlikenfnl_hook_dump()kernel-src-tree/net/netfilter/nf_tables_api.c
Line 1583 in f3e9580
This means the bug is accessible from the control plane as well.
kABI check: passed
Boot test: passed
boot-test.log
Kselftests: passed relative
Reference
kselftests–ciqlts8_6–run1.log
Patch
kselftests–ciqlts8_6-CVE-batch-46–run1.log
Comparison
The tests results for the reference and the patch are the same.
Results for the
netfiltersubsystem specifically:full-test-results-comparison.log
More targeted tests: passed relative
In the general, single-boot test runs, some of the netfilter tests
skiporfailas a result of selftests interference. Running them on a separate boot each gives better coverage.Unfortunately the
netfilter:nft_flowtable.shtest still fails, although more elaborately, and still in the same way as on the reference kernel.Bundled test:
Separate test:
(see the log files for details)
netfilter:conntrack_icmp_related.shkselftests–conntrack_icmp_related–ciqlts8_6–run1.log
kselftests–conntrack_icmp_related–ciqlts8_6–run2.log
kselftests–conntrack_icmp_related–ciqlts8_6–run3.log
kselftests–conntrack_icmp_related–ciqlts8_6-CVE-batch-46–run1.log
kselftests–conntrack_icmp_related–ciqlts8_6-CVE-batch-46–run2.log
kselftests–conntrack_icmp_related–ciqlts8_6-CVE-batch-46–run3.log
netfilter:conntrack_tcp_unreplied.shkselftests–conntrack_tcp_unreplied–ciqlts8_6–run1.log
kselftests–conntrack_tcp_unreplied–ciqlts8_6–run2.log
kselftests–conntrack_tcp_unreplied–ciqlts8_6–run3.log
kselftests–conntrack_tcp_unreplied–ciqlts8_6-CVE-batch-46–run1.log
kselftests–conntrack_tcp_unreplied–ciqlts8_6-CVE-batch-46–run2.log
kselftests–conntrack_tcp_unreplied–ciqlts8_6-CVE-batch-46–run3.log
netfilter:ipvs.shkselftests–ipvs–ciqlts8_6–run1.log
kselftests–ipvs–ciqlts8_6–run2.log
kselftests–ipvs–ciqlts8_6–run3.log
kselftests–ipvs–ciqlts8_6-CVE-batch-46–run1.log
kselftests–ipvs–ciqlts8_6-CVE-batch-46–run2.log
kselftests–ipvs–ciqlts8_6-CVE-batch-46–run3.log
netfilter:nft_flowtable.shkselftests–nft_flowtable–ciqlts8_6–run1.log
kselftests–nft_flowtable–ciqlts8_6–run2.log
kselftests–nft_flowtable–ciqlts8_6–run3.log
kselftests–nft_flowtable–ciqlts8_6-CVE-batch-46–run1.log
kselftests–nft_flowtable–ciqlts8_6-CVE-batch-46–run2.log
kselftests–nft_flowtable–ciqlts8_6-CVE-batch-46–run3.log
netfilter:nft_meta.shkselftests–nft_meta–ciqlts8_6–run1.log
kselftests–nft_meta–ciqlts8_6–run2.log
kselftests–nft_meta–ciqlts8_6–run3.log
kselftests–nft_meta–ciqlts8_6-CVE-batch-46–run1.log
kselftests–nft_meta–ciqlts8_6-CVE-batch-46–run2.log
kselftests–nft_meta–ciqlts8_6-CVE-batch-46–run3.log
netfilter:nft_nat.shkselftests–nft_nat–ciqlts8_6–run1.log
kselftests–nft_nat–ciqlts8_6–run2.log
kselftests–nft_nat–ciqlts8_6–run3.log
kselftests–nft_nat–ciqlts8_6-CVE-batch-46–run1.log
kselftests–nft_nat–ciqlts8_6-CVE-batch-46–run2.log
kselftests–nft_nat–ciqlts8_6-CVE-batch-46–run3.log
netfilter:nft_queue.shkselftests–nft_queue–ciqlts8_6–run1.log
kselftests–nft_queue–ciqlts8_6–run2.log
kselftests–nft_queue–ciqlts8_6–run3.log
kselftests–nft_queue–ciqlts8_6-CVE-batch-46–run1.log
kselftests–nft_queue–ciqlts8_6-CVE-batch-46–run2.log
kselftests–nft_queue–ciqlts8_6-CVE-batch-46–run3.log