LoongFire · 龙火 firewall · eBPF 防火墙 · eBPF

LoongFire XDP SYNPROXY: An Efficient Stopgap for CVE-2026-98432

LoongFire XDP SYNPROXY:针对 CVE-2026-98432 的高效临时缓解方案

Understanding the Vulnerability First

CVE-2026-98432 is a use-after-free (UAF) in the Linux kernel's IPv4 TCP connection handling. The root cause is a race condition: when tcp_v4_syn_recv_sock() transfers ireq->ireq_opt to the child socket, it transfers ownership rather than copying. Under concurrent conditions, another CPU processing a retransmitted SYN calls tcp_v4_send_synack(), which reads the IP options from ireq_opt — memory that may have already been freed via plain kfree() instead of kfree_rcu(). The final UAF manifests in ip_options_build().

There's also a second path involving request socket migration (e.g., net.ipv4.tcp_migrate_req=1 or BPF programs), where cloned request sockets share ireq_opt — but for the primary remote attack surface, the trigger point is the SYN/SYNACK handshake path.

The official guidance is clear: apply the kernel security update. Filtering is only a stopgap. But when a patch isn't yet deployed, how you implement that stopgap matters enormously.

Why Simple Firewall Rules Fall Short

A common first instinct is to block IP packets with options at the firewall. But there's a critical distinction:

  • Protecting the firewall itself (INPUT chain) does nothing for servers behind it.
  • Port-forwarded traffic traverses the FORWARD chain. If you only add DROP rules to INPUT, the firewall is protected but every backend server receiving forwarded traffic remains exposed — the packet with IP options reaches the backend kernel and can trigger the vulnerability there.
  • To cover the forwarding path, you must explicitly add rules to the FORWARD chain (e.g., IPFire's CUSTOMFORWARD), checking the IHL field and dropping packets where IHL > 5.

This works, but it means maintaining separate rules for INPUT and FORWARD, and the filtering happens relatively late — after the packet has already entered the netfilter framework.

The LoongFire XDP SYNPROXY Advantage

LoongFire's XDP SYNPROXY program runs at the earliest point in the packet receive path — in the network card driver, before the kernel protocol stack allocates socket memory or processes TCP options. By adding a simple check at the very beginning of the XDP program:

if (iph->ihl > 5)
    return XDP_DROP;

you get several compounding benefits:

1. Unified Protection for Local and Forwarded Traffic

XDP executes at ingress, before the routing decision. Whether the packet is ultimately destined for the firewall itself or forwarded to a backend server, the XDP program sees it first. A single XDP_DROP blocks both paths. No separate INPUT/FORWARD rules needed — the coverage is inherent to where XDP sits in the pipeline.

2. The Vulnerable Code Path Is Never Reached

Because XDP drops the packet before it enters the protocol stack, the kernel never allocates the request socket memory, never processes the TCP options, and never reaches ip_options_build(). This isn't just filtering — it's preventing the vulnerable code from executing at all.

3. Efficiency

Native XDP (driver mode) processes packets with minimal overhead compared to traversing netfilter. Even in generic (SKB) mode, it's earlier than iptables. For a firewall appliance handling high throughput, this matters.

4. Simplicity of Maintenance

One check in one program, attached to the ingress interface, covers the entire attack surface for remote packets. No rule duplication, no chain-specific configuration.

Caveats Worth Knowing

  • CIPSO/local generation path: If the host uses SELinux or Smack CIPSO tags, the kernel may attach IP options to locally generated packets. These don't traverse the XDP ingress hook, so XDP can't block them. However, for the external attack surface — remote packets arriving and being forwarded — XDP is effective. Hosts using CIPSO still need the kernel patch for complete coverage.
  • Interface coverage: Ensure the XDP program is attached to all external interfaces (WAN/red, VLAN sub-interfaces, etc.). A single unprotected ingress point is a gap.
  • XDP mode: Confirm native driver support on your hardware. Generic mode works but loses some efficiency advantage.
This is still a stopgap: XDP filtering is an emergency mitigation. The complete fix is updating to a patched kernel (IPFire has released Core Update 205 with kernel 6.18.60; LoongFire should have a corresponding update). Retaining the XDP rule afterward is reasonable defense-in-depth, but it shouldn't be the sole protection long-term.

Conclusion

For CVE-2026-98432, the final UAF does occur in IP option handling — but "blocking IP options" is only as good as where you block them. iptables rules require careful chain-by-chain configuration and still let packets enter the netfilter pipeline. LoongFire's XDP SYNPROXY, with an IHL check added at ingress, provides a stopgap that is earlier, simpler, and covers both local and forwarded traffic in one place — a genuinely efficient mitigation while the kernel patch is rolled out.

The patch remains the destination. But on the road there, XDP is the smarter stopgap.

先理解漏洞本身

CVE-2026-98432 是 Linux 内核 IPv4 TCP 连接处理中的一个释放后使用(use-after-free,UAF)漏洞。根本原因是一个竞态条件:当 tcp_v4_syn_recv_sock() 将 ireq->ireq_opt 转移到子套接字时,它转移的是所有权而非进行拷贝。在并发条件下,另一个 CPU 处理重传的 SYN 时会调用 tcp_v4_send_synack(),后者从 ireq_opt 读取 IP 选项——而这部分内存可能已经通过普通的 kfree()(而非 kfree_rcu())被释放。最终的 UAF 在 ip_options_build() 中显现。

还有第二条路径涉及请求套接字迁移(例如 net.ipv4.tcp_migrate_req=1 或 BPF 程序),其中克隆的请求套接字共享 ireq_opt——但对于主要的远程攻击面,触发点仍然是 SYN/SYNACK 握手路径。

官方指引很明确:应用内核安全更新。过滤只是临时缓解。但当补丁尚未部署时,如何实施这一临时缓解至关重要。

为什么简单防火墙规则不够用

常见的直觉做法是在防火墙上阻止带 IP 选项的报文。但这里有一个关键区别:

  • 保护防火墙自身(INPUT 链)对身后的服务器毫无帮助。
  • 端口转发流量会经过 FORWARD 链。如果你只在 INPUT 链添加 DROP 规则,防火墙是受保护了,但每一台接收转发流量的后端服务器仍然暴露——带 IP 选项的报文会到达后端内核,并在那里触发漏洞。
  • 要覆盖转发路径,必须显式地在 FORWARD 链(例如 IPFire 的 CUSTOMFORWARD)添加规则,检查 IHL 字段并丢弃 IHL > 5 的报文。

这样做有效,但意味着要为 INPUT 和 FORWARD 分别维护规则,而且过滤发生得相对较晚——报文已经进入 netfilter 框架之后。

LoongFire XDP SYNPROXY 的优势

LoongFire 的 XDP SYNPROXY 程序运行在报文接收路径的最早位置——在网络卡驱动中,早于内核协议栈分配套接字内存或处理 TCP 选项。只需在 XDP 程序的最开始添加一个简单的检查:

if (iph->ihl > 5)
    return XDP_DROP;

就能获得多重复合收益:

1. 统一保护本机与转发流量

XDP 在入口处执行,早于路由决策。无论报文最终是发往防火墙本身还是转发到后端服务器,XDP 程序都会先看到它。一次 XDP_DROP 同时阻断两条路径。无需分别维护 INPUT/FORWARD 规则——覆盖率是 XDP 在流水线中所处位置的内在属性。

2. 漏洞代码路径根本不会被触达

由于 XDP 在报文进入协议栈之前就将其丢弃,内核从不会分配请求套接字内存,从不会处理 TCP 选项,也永远不会到达 ip_options_build()。这不仅是过滤——而是从根本上阻止了有漏洞的代码执行。

3. 高效

原生 XDP(驱动模式)处理报文的开销远小于穿越 netfilter。即使在通用(SKB)模式下,也比 iptables 更早。对于处理高吞吐量的防火墙设备,这一点很重要。

4. 维护简单

一个程序中的一处检查,附加到入口接口,就覆盖了远程报文的整个攻击面。没有规则重复,没有针对不同链的专门配置。

值得了解的注意事项

  • CIPSO/本地生成路径:如果主机使用 SELinux 或 Smack CIPSO 标签,内核可能会为本机生成的报文附加 IP 选项。这些报文不经过 XDP 入口钩子,因此 XDP 无法阻止它们。然而,对于外部攻击面——即到达并被转发的远程报文——XDP 是有效的。使用 CIPSO 的主机仍需内核补丁才能获得完整覆盖。
  • 接口覆盖:确保 XDP 程序附加到所有外部接口(WAN/red、VLAN 子接口等)。任何单个未受保护的入口点都是一个缺口。
  • XDP 模式:确认你的硬件支持原生驱动模式。通用模式可用,但会损失部分效率优势。
这仍然是临时缓解:XDP 过滤是应急措施。完整的修复是更新到已打补丁的内核(IPFire 已发布带内核 6.18.60 的 Core Update 205;LoongFire 应有相应的更新)。事后保留 XDP 规则作为纵深防御是合理的,但不应成为长期的唯一防护。

结论

对于 CVE-2026-98432,最终的 UAF 确实发生在 IP 选项处理中——但"阻止 IP 选项"的效果取决于你在哪里阻止它们。iptables 规则需要逐链仔细配置,而且仍会让报文进入 netfilter 流水线。LoongFire 的 XDP SYNPROXY 在入口处添加 IHL 检查,提供了一种更早、更简单、且在一处同时覆盖本机与转发流量的临时缓解方案——在内核补丁推广期间,这是一种真正高效的缓解措施。

补丁仍是最终目标。但在通往目标的路上,XDP 是更聪明的临时方案。

All posts全部文章 Home首页