CVE-2026-97608 PUBLISHED

netfilter: nf_log: unregister loggers before per-net teardown

Assigner: Linux
Reserved: 24.09.2026 Published: 25.09.2026 Updated: 25.09.2026

In the Linux kernel, the following vulnerability has been resolved:

netfilter: nf_log: unregister loggers before per-net teardown

nf_log_syslog and nfnetlink_log unregister their per-network namespace operations before unregistering their global logger backends. This leaves a window where a sysctl or netlink writer can rebind the still- registered logger after the per-net pre-exit callback cleared the old selection.

The race looks like this:

CPU 0 CPU 1 ---- ---- unregister_pernet_subsys() nf_log_unset(net, logger) net->nf.nf_loggers[pf] = NULL

<pre> lock nf_log_mutex find logger in loggers[][] net->nf.nf_loggers[pf] = logger unlock nf_log_mutex </pre>

nf_log_unregister(logger) lock nf_log_mutex loggers[pf][type] = NULL unlock nf_log_mutex synchronize_rcu() module exit returns module core frees backend memory

Later, a sysctl read or packet logging operation can dereference the stale per-net logger pointer.

Fix this by unregistering the global logger backends before tearing down per-net state. Once the global registrations are gone, later writers can no longer rebind the logger. unregister_pernet_subsys() already waits for an RCU grace period after the pre-exit callback clears the per-net selection, while nf_log_unregister() continues to cover readers of the global logger table.

Apply this ordering fix to both nf_log backends that combine per-net teardown with global logger registration.

Metrics

CVSS Vector: CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS Score: 7

AV:L - Both sides of the race are local. One is module exit (nf_log_syslog_exit or nfnetlink_log_fini through delete_module). The other is a write to the net.netfilter.nf_log.<pf> sysctl, handled by nf_log_proc_dostring(), or an NFULNL_CFG_CMD_PF_BIND message over nfnetlink. No remote peer supplies anything that causes the stale nf_loggers[] pointer. AC:H - The attacker controls the rebind side, but the other side is a module unload that needs init-namespace CAP_SYS_MODULE. The attacker cannot make it happen. They must win the short window between nf_log_unset() in the per-net pre-exit and nf_log_unregister() while an admin unloads the module. PR:L - nf_log_proc_dostring() rebinds net->nf.nf_loggers[pf] from the per-netns sysctl, which is writable in a non-init netns. The nfnetlink PF_BIND path only checks netlink_net_capable(CAP_NET_ADMIN). So user namespaces (unshare -Urn) are enough for the attacker's side. UI:N - No victim action on attacker-supplied content is needed. The module unload is an admin action outside the attacker's control and is already counted under AC:H. S:U - The stale logger pointer is used inside the same kernel. Nothing crosses a VM, IOMMU or other security boundary. C:H - After the module is freed, a sysctl read dereferences logger->name, and nf_log_packet() calls logger->logfn through the dangling nf_loggers[pf] pointer. This is a use-after-free of freed module memory that can be leveraged to disclose kernel memory. I:H - nf_log_packet() makes an indirect call through logger->logfn in the freed module's memory. If that memory is reused, this gives control-flow hijacking and memory corruption. A:H - Logging a packet, or reading the sysctl, after the logger module is gone faults on the unmapped or reused module memory and oopses the kernel.

Product Status

Vendor Linux
Product Linux
Versions Default: unaffected
  • affected from 5b023fc8d8e0997e0b7ea6506d243afd5478c96e to eaec35fae8f2052c1878a5c7cc7699d8357d79f2 (excl.)
  • affected from 5b023fc8d8e0997e0b7ea6506d243afd5478c96e to 64803ba0a05791cf9ca874466480e4c4cadaf7ab (excl.)
  • affected from 5b023fc8d8e0997e0b7ea6506d243afd5478c96e to dce24f3a146948595bb1b86347f31e20b4975daa (excl.)
  • affected from 5b023fc8d8e0997e0b7ea6506d243afd5478c96e to 2c018cc4842c33f0c732962e2ab58635e8ae5823 (excl.)
Vendor Linux
Product Linux
Versions Default: affected
  • Version 3.10 is affected
  • unaffected from 0 to 3.10 (excl.)
  • unaffected from 6.12.111 to 6.12.* (incl.)
  • unaffected from 6.18.53 to 6.18.* (incl.)
  • unaffected from 7.2.7 to 7.2.* (incl.)
  • unaffected from 7.3-rc3 to * (incl.)

References